package com.cvte.shop.service.impl;

import com.cvte.csb.core.interfaces.vo.RestResponse;
import com.cvte.csb.web.rest.ResponseFactory;
import com.cvte.shop.constants.UniversalResultFieldsConstants;
import com.cvte.shop.constants.UserConstants;
import com.cvte.shop.entity.*;
import com.cvte.shop.entity.dto.ConditionDTO;
import com.cvte.shop.entity.dto.TableDTO;
import com.cvte.shop.entity.vo.TableVo;
import com.cvte.shop.enums.RestResponceEnum;
import com.cvte.shop.exception.BaseBusinessException;
import com.cvte.shop.mapper.UniversalMethodResultMapper;
import com.cvte.shop.mapper.UniversalResultFieldsMapper;
import com.cvte.shop.mapper.UniversalViewConfigMapper;
import com.cvte.shop.service.*;
import com.cvte.shop.util.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.cvte.csb.jdbc.mybatis.biz.BaseBiz;
import com.cvte.shop.mapper.UniversalTableConfigMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 服务实现类
 *
 * @author inv
 * @since 2020-08-04
 */
@Service
@Transactional
public class UniversalTableConfigServiceImpl extends BaseBiz<UniversalTableConfigMapper, UniversalTableConfig> implements UniversalTableConfigService {

    @Autowired
    private UniversalTableConfigMapper universalTableConfigMapper;

    @Autowired
    private UniversalResultFieldsMapper universalResultFieldsMapper;

    @Autowired
    private UniversalDefinedConditionService universalDefinedConditionService;

    @Autowired
    private UniversalBasicConditionService universalBasicConditionService;

    @Autowired
    private UniversalMethodResultService universalMethodResultService;

    @Autowired
    private UniversalResultFieldsService universalResultFieldsService;

    @Autowired
    private UniversalViewConfigService universalViewConfigService;

    @Autowired
    private UniversalViewConfigMapper universalViewConfigMapper;

    @Autowired
    private UniversalMethodResultMapper universalMethodResultMapper;

    private static String VIEW_PRIFIX = "TABLE_";


    @Override
    public RestResponse addTableConfig(TableDTO tableDTO) {

        String tableName = tableDTO.getTableName();
        String resultSet = tableDTO.getResultSet();
        String tableFlag = tableDTO.getTableFlag();
        try {
            // 核对sql是否正确
            universalMethodResultService.checkSql(resultSet);

            // 插入表配置
            UniversalTableConfig universalTableConfig = new UniversalTableConfig();
            String tableId = UUIDUtil.getUUID();
            universalTableConfig.setTableId(tableId);
            universalTableConfig.setTableName(tableName);
            universalTableConfig.setResultSet(resultSet);
            universalTableConfigMapper.insert(universalTableConfig);

            // 将对应的字段放入配置信息
            List<UniversalResultFields> fieldList = insertFields(tableId, resultSet, tableFlag);

            // 生成view视图
            UniversalViewConfig view = universalViewConfigService.createView(tableId, UniversalResultFieldsConstants.DEAULT_VIEW_ID);

            // 生成sql
            universalMethodResultService.createInitTableSql(fieldList, tableId, view.getViewId());

            // 配置返回前端的视图信息
            TableVo tableVo = new TableVo(universalTableConfig, fieldList, view);

            return ResponseFactory.getOkResponse(tableVo);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseBusinessException(RestResponceEnum.INSERT_ERROR.getCode(), RestResponceEnum.INSERT_ERROR.getMessage());
        }
    }

    @Override
    public RestResponse addCondition(ConditionDTO conditionDTO) {
        String viewId = conditionDTO.getViewId();
        String tableId = conditionDTO.getTableId();

        boolean flag = false;

        if (conditionDTO == null) {
            throw new BaseBusinessException(RestResponceEnum.ARGUMENTS_ERROR.getCode(), RestResponceEnum.ARGUMENTS_ERROR.getMessage());
        }
        List<UniversalDefinedCondition> definedConditionList = conditionDTO.getDefinedConditionList();
        if (!(definedConditionList == null || definedConditionList.size() == 0)) {
            universalDefinedConditionService.addCondition(definedConditionList,viewId,tableId);
            flag = true;
        }
        List<UniversalBasicCondition> basicConditionList = conditionDTO.getBasicConditionList();
        if (!(basicConditionList == null || basicConditionList.size() == 0)) {
            universalBasicConditionService.addCondition(basicConditionList,viewId,tableId);
            flag = true;
        }
        if (flag) {
            // 添加条件
            commonUpdateSql(basicConditionList, definedConditionList, tableId,viewId);
            return ResponseFactory.getOkResponse(null);
        }
        return ResponseFactory.buildResult(RestResponceEnum.INSERT_ERROR.getMessage(), RestResponceEnum.INSERT_ERROR.getCode(), null);
    }


    /**
     * 插入查询的字段信息
     *
     * @param tableId   表信息的id
     * @param resultSet 结果集：视图、表、结果集
     * @param tableFlag 如果不为null说明是结果集
     */
    private List<UniversalResultFields> insertFields(String tableId, String resultSet, String tableFlag) {
        if (StringUtils.isNotBlank(tableFlag)) {
            // 结果集操作，首先创建视图。
            String viewName = VIEW_PRIFIX + UUIDUtil.getUUID().substring(0, 5);
            createView(viewName, resultSet);
            resultSet = viewName;
        }
        // 根据结果查询对应的字段信息
        List<UniversalResultFields> list = universalTableConfigMapper.selectFieidByTableName(resultSet.toUpperCase());

        if (StringUtils.isNotBlank(tableFlag)) {
            deleteView(resultSet);
        }
        // 插入字段
        universalResultFieldsService.batchInsertFields(list, tableId, UniversalResultFieldsConstants.DEAULT_VIEW_ID);


        return list;
    }

    /**
     * 删除视图
     *
     * @param viewName
     */
    private void deleteView(String viewName) {
        universalTableConfigMapper.deleteView(viewName);

    }

    /**
     * 创建视图
     *
     * @param viewName
     * @param resultSet
     */
    private void createView(String viewName, String resultSet) {
        universalTableConfigMapper.createView(viewName, resultSet);
    }


    private void commonUpdateSql(List<UniversalBasicCondition> basicConditionList, List<UniversalDefinedCondition> definedConditionList, String tableId,String viewId){
        String sqlContext = universalMethodResultMapper.selectSqlContextByTableId(tableId, viewId);

        if(!StringUtils.isNotBlank(sqlContext)){
            throw new BaseBusinessException("500005","根据tableid和viewid未找到对应的sql");
        }

        StringBuilder builder = new StringBuilder(sqlContext);
        builder.append(" and ( ");
        // 创建sql
        boolean flag =  createBasicCondition(builder,basicConditionList);
        createDefinedCondition(builder,definedConditionList,flag);

        builder.append(" ) ");

        String result = builder.toString();
        universalMethodResultService.checkSql(result);

        // 更新到数据库
        universalMethodResultMapper.updateSqlContextByTableId(result, tableId, viewId);
    }

    @Override
    public boolean createBasicCondition(StringBuilder builder, List<UniversalBasicCondition> basicConditionList){

        //拼接sql
        if (basicConditionList != null && basicConditionList.size() != 0) {
            Collections.sort(basicConditionList, new MyBasicComparator());
            for (UniversalBasicCondition basicCondition : basicConditionList) {
                if(!basicCondition.equals(basicConditionList.get(0))){
                    builder.append(" "+basicCondition.getLogicSymbol());
                }
                String bracket = basicCondition.getLeftBrackets() == null ? "" : basicCondition.getLeftBrackets();
                builder.append(" " + bracket);
                builder.append(" " + basicCondition.getConditionName());
                builder.append(" " + basicCondition.getOperation());
                builder.append(" " + " '" + basicCondition.getFiledContext() + "'");

                bracket = basicCondition.getRightBrackets() == null ? "" : basicCondition.getRightBrackets();
                builder.append(" " + bracket);
            }
            return true;
        }
        return false;
    }

    @Override
    public void createDefinedCondition(StringBuilder builder, List<UniversalDefinedCondition> definedConditionList,boolean flag){
        if (definedConditionList != null && definedConditionList.size() != 0) {
            Collections.sort(definedConditionList, new MyDefinedComparator());
            for (UniversalDefinedCondition definedCondition : definedConditionList) {
                if(flag || !definedCondition.equals(definedConditionList.get(0))){
                    builder.append(" " + definedCondition.getLogicSymbol());
                    flag = false;
                }
                builder.append(" " + definedCondition.getConditionContext());
            }
        }
    }


    private class MyBasicComparator implements Comparator<UniversalBasicCondition> {

        @Override
        public int compare(UniversalBasicCondition o1, UniversalBasicCondition o2) {
            return o1.getSeq() - o2.getSeq();
        }
    }

    private class MyDefinedComparator implements Comparator<UniversalDefinedCondition> {

        @Override
        public int compare(UniversalDefinedCondition o1, UniversalDefinedCondition o2) {
            return o1.getSeq() - o2.getSeq();
        }
    }

}
